package com.opennews.openplatform.service;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.opennews.openplatform.dto.app.error.report.AppErrorReportDto;
import com.opennews.openplatform.entity.tables.records.AppErrorReportRecord;
import com.opennews.openplatform.myspringbootcore.util.SharedUtil;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.jooq.DSLContext;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

import static com.opennews.openplatform.entity.Tables.APP_ERROR_REPORT;

@RequiredArgsConstructor
@Service
public class AppErrorReportService {
    private final DSLContext dslContext;
    private final ObjectMapper objectMapper;

    /**
     * Saves error report sent from app.
     */
    public void save(@Valid AppErrorReportDto data) {
        Map<String, Object> mapData = objectMapper.convertValue(data, HashMap.class);

        // If deviceInfo contains map instance then we need to converts it to string type.
        try {
            String json = objectMapper.writeValueAsString(data.getDeviceInfo());
            mapData.put("deviceInfo", json);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        // If systemInfo contains map instance then we need to converts it to string type.
        try {
            String json = objectMapper.writeValueAsString(data.getSystemInfo());
            mapData.put("systemInfo", json);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }

        // Converts keys to snake case for database column names since record.formMap() expects key to be the same as column name.
        Map<String, Object> convertedMapData = new HashMap<>();

        mapData.forEach((key, value) -> {
            convertedMapData.put(SharedUtil.convertCamelToSnake(key), value);
        });

        // Creates a new AppErrorReport with provided data.
        AppErrorReportRecord record = dslContext.newRecord(APP_ERROR_REPORT);
        record.fromMap(convertedMapData);
        record.insert();
    }
}
